package com.ethink.platform.controller.order;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.framework.common.web.BaseController;
import com.ethink.framework.common.web.context.SPRequestContextHolder;
import com.ethink.framework.common.web.response.CommonResponse;
import com.ethink.mdm.api.component.MdmComponent;
import com.ethink.mdm.api.info.CurrencyInfo;
import com.ethink.order.api.TobSaleOrderFacade;
import com.ethink.order.api.enums.TobSaleOrderOrderStatusEnum;
import com.ethink.order.api.info.TobSaleDetailOrderInfo;
import com.ethink.order.api.info.TobSaleOrderInfo;
import com.ethink.order.api.model.TobSaleAndSettleModel;
import com.ethink.order.api.model.TobSaleOrderGoodsModeModel;
import com.ethink.order.api.model.TobSaleOrderModel;
import com.ethink.order.api.request.*;
import com.ethink.order.api.response.TobSaleOrderAddResponse;
import com.ethink.order.api.response.TobSaleOrderDetailResponse;
import com.ethink.platform.common.properties.PlatformCommonProperties;
import com.ethink.platform.controller.order.info.ExportInfo;
import com.ethink.platform.controller.order.info.TobSaleImportInfo;
import com.ethink.platform.manager.ExportManager;
import com.ethink.platform.manager.TobSaleManager;
import com.ethink.system.api.SystemTodoFacade;
import com.ethink.system.api.enums.SystemTodoTodoTypeEnum;
import com.ethink.system.api.request.SystemTodoAddRequest;
import com.ethink.warehouse.api.LogisticsTraceApplyOrderFacade;
import com.ethink.warehouse.api.MateInventoryOrderFacade;
import com.ethink.warehouse.api.SubWarehouseFacade;
import com.ethink.warehouse.api.enums.SubjectEnum;
import com.ethink.warehouse.api.info.SubWarehouseInfo;
import com.ethink.warehouse.api.request.LogisticsTraceApplyDeleteRequest;
import com.ethink.warehouse.api.request.LogisticsTraceOrderTypeOrderListRequest;
import com.ethink.warehouse.api.response.LogisticsTraceOrderNoOrderDetailResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author default
 * @version 1.0.0
 * @ClassName TobSaleOrderController.java
 * @Description
 * @createTime 2022年11月16日 13:49:00
 */
@Tag(name = "TobSaleOrderController", description = "Tob销/预售单 Controller")
@RestController
@Slf4j
@RequestMapping("platform-server/v1/order-service")
public class TobSaleOrderController extends BaseController {


    @Autowired
    private TobSaleOrderFacade tobSaleOrderFacade;

    @Autowired
    private TobSaleManager tobSaleManager;

    @Autowired
    private SubWarehouseFacade subWarehouseFacade;

    @Autowired
    private PlatformCommonProperties commonProperties;

    @Autowired
    private SystemTodoFacade systemTodoFacade;

    @Autowired
    private LogisticsTraceApplyOrderFacade logisticsTraceApplyOrderFacade;

    @Autowired
    private MdmComponent mdmComponent;

    @Autowired
    private ExportManager exportManager;

    @Operation(summary = "新增")
    @PostMapping("/tobSale/add")
    public CommonResponse addTobSaleOrder(@Validated @RequestBody TobSaleOrderAddRequest request) {
        request.setCreateUserName(SPRequestContextHolder.getCurrentSystemUserRealName());
        request.setCreateUserCode(SPRequestContextHolder.getCurrentSystemUserLoginName());
        SubWarehouseInfo subWarehouse = subWarehouseFacade.getSubWarehouseByCode(request.getOutSubWarehouseCode());
        request.setOutSubWarehouseName(subWarehouse.getSubWarehouseName());
        CurrencyInfo currency = mdmComponent.getCurrency(request.getCurrencyCode());
        request.setCurrencyName(currency.getName());
        request.setCurrencyCode(currency.getCode());
        TobSaleOrderAddResponse response = tobSaleOrderFacade.addTobSaleOrder(request);
        if (TobSaleOrderOrderStatusEnum.S2.eq(request.getOrderStatus())) {
            try {
                tobSaleManager.tobApply(response.getTobSaleOrderInfo(), response.getTobSaleDetailOrderInfoList());
            } catch (Exception e) {
                log.error("锁单失败：" + e);
                TobSaleOrderSetStatusRequest tobSaleOrderSetStatusRequest = new TobSaleOrderSetStatusRequest();
                tobSaleOrderSetStatusRequest.setId(response.getTobSaleOrderInfo().getId());
                tobSaleOrderSetStatusRequest.setOrderStatus(TobSaleOrderOrderStatusEnum.S1.getIntValue());
                tobSaleOrderFacade.updateTobSaleOrderStatus(tobSaleOrderSetStatusRequest);
            }
        }
        return succeed();
    }

    @Operation(summary = "预售单分页查询")
    @GetMapping("/tobSale/pageQuery")
    public CommonResponse<List<TobSaleOrderModel>> pageQueryTobSaleOrder(TobSaleOrderPageQueryRequest request) {
        Page<TobSaleOrderModel> tobSaleOrderModelPage = tobSaleOrderFacade.pageQueryTobSaleOrder(request);
        Map<String, SubWarehouseInfo> subWarehouseMap = subWarehouseFacade.listSubWarehouse()
                .stream().collect(Collectors.toMap(SubWarehouseInfo::getSubWarehouseCode, info -> info));

        if (CollectionUtils.isNotEmpty(tobSaleOrderModelPage.getRecords())) {
            LogisticsTraceOrderTypeOrderListRequest logisticsTraceOrderTypeOrderListRequest = new LogisticsTraceOrderTypeOrderListRequest();
            logisticsTraceOrderTypeOrderListRequest.setSourceOrderType(SubjectEnum.T42.getCode());
            logisticsTraceOrderTypeOrderListRequest.setSourceOrderNoList(tobSaleOrderModelPage.getRecords()
                    .stream().map(TobSaleOrderModel::getOrderNo).distinct().collect(Collectors.toList()));
            List<LogisticsTraceOrderNoOrderDetailResponse> logisticsTraceOrderNoOrderDetailResponseList = logisticsTraceApplyOrderFacade.listLogisticsTraceOrderNoOrderDetail(logisticsTraceOrderTypeOrderListRequest);
            Map<String, Boolean> canRemoveMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(logisticsTraceOrderNoOrderDetailResponseList)) {
                for (LogisticsTraceOrderNoOrderDetailResponse detailResponse : logisticsTraceOrderNoOrderDetailResponseList) {
                    canRemoveMap.put(detailResponse.getSourceOrderNo(), detailResponse.getTraceQty() == 0);
                }
            }
            for (TobSaleOrderModel record : tobSaleOrderModelPage.getRecords()) {
                SubWarehouseInfo subWarehouseInfo = subWarehouseMap.get(record.getInSubWarehouseCode());
                if (subWarehouseInfo != null) {
                    record.setWarehouseCode(subWarehouseInfo.getWarehouseCode());
                    record.setWarehouseName(subWarehouseInfo.getWarehouseName());
                }
                Boolean canRemove = canRemoveMap.get(record.getOrderNo());
                record.setIsRemove(canRemove == null ? true : canRemove);
            }
        }
        return succeedWithPage(tobSaleOrderModelPage);
    }

    @Operation(summary = "预售单导出Excel")
    @GetMapping("/tobSale/export")
    public CommonResponse<ExportInfo> exportTobSaleOrder(TobSaleOrderPageQueryRequest request) {
        return succeedWith(exportManager.exportTobSaleOrder(request));
    }

    @Operation(summary = "货品模式切换预售单分页查询")
    @GetMapping("/tobSale/pageGoodsModeQuery")
    public CommonResponse<List<TobSaleOrderGoodsModeModel>> pageQueryTobSaleOrderPageMode(TobSaleOrderPageGoodsModeQueryRequest request) {
        Page<TobSaleOrderGoodsModeModel> tobSaleOrderGoodsModeModelPage = tobSaleOrderFacade.pageQueryTobSaleOrderPageMode(request);
        return succeedWithPage(tobSaleOrderGoodsModeModelPage);
    }

    @Operation(summary = "预售单货品模式导出Excel")
    @GetMapping("/tobSale/exportGoodsMode")
    public CommonResponse<ExportInfo> exportTobSaleOrderGoodsMode(TobSaleOrderPageGoodsModeQueryRequest request) {
        return succeedWith(exportManager.exportTobSaleOrderGoodsMode(request));
    }

    @Operation(summary = "预售单详情主数据")
    @GetMapping("/tobSale/query/{id}")
    public CommonResponse<TobSaleOrderInfo> queryTobSaleOrderById(@PathVariable("id") Long id) {
        TobSaleOrderInfo tobSaleOrderInfo = tobSaleOrderFacade.queryTobSaleOrderById(id);
        SubWarehouseInfo subWarehouseInfo = subWarehouseFacade.getSubWarehouseByCode(tobSaleOrderInfo.getOutSubWarehouseCode());
        tobSaleOrderInfo.setWarehouseCode(subWarehouseInfo.getWarehouseCode());
        tobSaleOrderInfo.setWarehouseName(subWarehouseInfo.getWarehouseName());
        return succeedWith(tobSaleOrderInfo);
    }

    @Operation(summary = "预售单详情table数据 table = 1  预售明细 table = 2 结算单明细")
    @GetMapping("/tobSale/query/{id}/{table}")
    public CommonResponse<TobSaleOrderDetailResponse> queryDetailTobSaleOrder(@PathVariable("id") Long id,
                                                                              @PathVariable("table") Integer table) {
        TobSaleOrderDetailResponse response = tobSaleOrderFacade.queryDetailTobSaleOrder(id, table);
       /* if (table == 1 && CollectionUtils.isNotEmpty(response.getSaleItem())) {
            List<MateInventoryDetailInfo> mateInventoryDetailInfoList = mateInventoryFacade.listMateInventoryByIdList(response.getSaleItem()
                    .stream().map(TobSaleDetailOrderInfo::getMateInventoryId).distinct()
                    .collect(Collectors.toList()));
            Map<Long, MateInventoryDetailInfo> mateInventoryDetailInfoMap = mateInventoryDetailInfoList.stream()
                    .collect(Collectors.toMap(MateInventoryDetailInfo::getId, info -> info));
            for (TobSaleDetailOrderInfo orderInfo : response.getSaleItem()) {
                MateInventoryDetailInfo mateInventoryDetailInfo = mateInventoryDetailInfoMap.get(orderInfo.getMateInventoryId());
                //orderInfo.setAvailableQty(mateInventoryDetailInfo.getAvailableQty());
            }
        }*/
        return succeedWith(response);
    }


    @Operation(summary = "作废/删除")
    @DeleteMapping("/tobSale/delete/{id}")
    public CommonResponse deleteTobSaleOrder(@PathVariable("id") Long id) {
        TobSaleOrderInfo tobSaleOrderInfo = tobSaleOrderFacade.queryTobSaleOrderById(id);
        if (TobSaleOrderOrderStatusEnum.S2.eq(tobSaleOrderInfo.getOrderStatus())) {
            TobSaleOrderDetailResponse response = tobSaleOrderFacade.queryDetailTobSaleOrder(id, 1);
            try {
                tobSaleManager.tobRelease(tobSaleOrderInfo, response.getSaleItem());
            } catch (Exception e) {
                log.error("库存释放失败", e);
                throw new BusinessException(CommonRespCode.PARAM_ERR, "库存释放失败");
            }
        } else if (TobSaleOrderOrderStatusEnum.S3.eq(tobSaleOrderInfo.getOrderStatus())) {
            TobSaleOrderDetailResponse response = tobSaleOrderFacade.queryDetailTobSaleOrder(id, 1);
            LogisticsTraceApplyDeleteRequest deleteRequest = new LogisticsTraceApplyDeleteRequest();
            deleteRequest.setSourceOrderNo(tobSaleOrderInfo.getOrderNo());
            deleteRequest.setSourceOrderType(SubjectEnum.T42.getCode());
            deleteRequest.setSourceDetailOrderNoList(response.getSaleItem().stream()
                    .map(TobSaleDetailOrderInfo::getDetailOrderNo).collect(Collectors.toList()));
            try {
                logisticsTraceApplyOrderFacade.deleteLogisticsTraceApply(deleteRequest);
            } catch (Exception e) {
                log.error("待出申请删除失败", e);
                throw new BusinessException(CommonRespCode.PARAM_ERR, "待出申请删除失败");
            }
            try {
                tobSaleManager.tobRelease(tobSaleOrderInfo, response.getSaleItem());
            } catch (Exception e) {
                log.error("库存释放失败", e);
                throw new BusinessException(CommonRespCode.PARAM_ERR, "库存释放失败");
            }
        } else if (TobSaleOrderOrderStatusEnum.S4.eq(tobSaleOrderInfo.getOrderStatus())) {
            throw new BusinessException(CommonRespCode.PARAM_ERR, "当前订单不能作废");
        } else if (TobSaleOrderOrderStatusEnum.S5.eq(tobSaleOrderInfo.getOrderStatus())) {
            throw new BusinessException(CommonRespCode.PARAM_ERR, "当前订单不能作废");
        }

        tobSaleOrderFacade.deleteTobSaleOrder(id);
        return succeed();
    }

    @Operation(summary = "修改")
    @PutMapping("/tobSale/update")
    public CommonResponse updateTobSaleOrder(@RequestBody @Validated TobSaleOrderUpdateRequest request) {
        CurrencyInfo currency = mdmComponent.getCurrency(request.getCurrencyCode());
        request.setCurrencyName(currency.getName());
        request.setCurrencyCode(currency.getCode());
        tobSaleOrderFacade.updateTobSaleOrder(request);
        if (TobSaleOrderOrderStatusEnum.S2.eq(request.getOrderStatus())) {
            TobSaleOrderInfo tobSaleOrderInfo = tobSaleOrderFacade.queryTobSaleOrderById(request.getId());
            TobSaleOrderDetailResponse response = tobSaleOrderFacade.queryDetailTobSaleOrder(request.getId(), 1);
            try {
                tobSaleManager.tobApply(tobSaleOrderInfo, response.getSaleItem());
            } catch (Exception e) {
                log.error("锁单失败：" + e);
                TobSaleOrderSetStatusRequest tobSaleOrderSetStatusRequest = new TobSaleOrderSetStatusRequest();
                tobSaleOrderSetStatusRequest.setId(request.getId());
                tobSaleOrderSetStatusRequest.setOrderStatus(TobSaleOrderOrderStatusEnum.S1.getIntValue());
                tobSaleOrderFacade.updateTobSaleOrderStatus(tobSaleOrderSetStatusRequest);
            }
        }
        return succeed();
    }


    @Operation(summary = "导入")
    @PostMapping("/tobSale/import")
    public CommonResponse<List<TobSaleImportInfo>> importTobSaleOrder(
            @RequestParam("subWarehouseCode") String subWarehouseCode,
            @RequestParam("saleSubChannel") String saleSubChannel,
            @RequestParam("file") MultipartFile file) {
        if (StringUtils.isBlank(subWarehouseCode) || StringUtils.isBlank(saleSubChannel)) {
            throw new BusinessException(CommonRespCode.PARAM_ERR, "请先选择仓库和渠道");
        }
        return succeedWith(tobSaleManager.importTobSaleOrder(subWarehouseCode, saleSubChannel, file));
    }


    @Operation(summary = "tob销售单分页查询")
    @GetMapping("/tobSaleSettle/pageQuery")
    public CommonResponse<List<TobSaleAndSettleModel>> tobSaleAndSettlePageQuery(TobSaleAndSettlePageQueryRequest request) {
        Page<TobSaleAndSettleModel> page = tobSaleOrderFacade.tobSaleAndSettlePageQuery(request);
        return succeedWithPage(page);
    }

    @Operation(summary = "修改订单状态")
    @PutMapping("/tobSale/setOrderStatus")
    public CommonResponse updateTobSaleOrderStatus(@RequestBody @Validated TobSaleOrderSetStatusRequest request) {
        tobSaleOrderFacade.updateTobSaleOrderStatus(request);
        if (TobSaleOrderOrderStatusEnum.S1.eq(request.getOrderStatus())) {
            TobSaleOrderInfo tobSaleOrderInfo = tobSaleOrderFacade.queryTobSaleOrderById(request.getId());
            TobSaleOrderDetailResponse response = tobSaleOrderFacade.queryDetailTobSaleOrder(request.getId(), 1);
            tobSaleManager.tobRelease(tobSaleOrderInfo, response.getSaleItem());

        } else if (TobSaleOrderOrderStatusEnum.S3.eq(request.getOrderStatus())) {
            TobSaleOrderInfo tobSaleOrderInfo = tobSaleOrderFacade.queryTobSaleOrderById(request.getId());
            TobSaleOrderDetailResponse response = tobSaleOrderFacade.queryDetailTobSaleOrder(request.getId(), 1);
            tobSaleManager.tobApplyPass(tobSaleOrderInfo, response.getSaleItem());
            //创建代办事项
            try {
                SystemTodoAddRequest addRequest = new SystemTodoAddRequest();
                addRequest.setRoleName(commonProperties.getLogisticsRoleName());
                addRequest.setTodoType(SystemTodoTodoTypeEnum.T5.getIntValue());
                addRequest.setDataId(tobSaleOrderInfo.getOrderNo());
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("orderNo", tobSaleOrderInfo.getOrderNo());
                addRequest.setTodoMessage(jsonObject.toJSONString());
                systemTodoFacade.addSystemTodo(addRequest);
            } catch (Exception e) {
                log.error("生成待办失败", e);
            }
        }
        return succeed();
    }

    @Operation(summary = "PO单号补充")
    @PutMapping("/tobSale/poInsert")
    public CommonResponse TobSaleOrderPoInsert(@Validated @RequestBody TobSaleOrderPoInsertRequest request) {
        tobSaleOrderFacade.TobSaleOrderPoInsert(request);
        return succeed();
    }

}
